package org.linlinjava.litemall.wx;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 用ReadWriteLock读写锁来实现一个高效的Map缓存
 *
 * @author zhy
 * @create 2018-11-18 13:47
 **/
public class ReadAndWriteLock<K,V> {
	private final ReadWriteLock lock = new ReentrantReadWriteLock();
	private final Lock readLock = lock.readLock();
	private final Lock writeLock = lock.writeLock();
	private final Map<K,V> map;

	public ReadAndWriteLock(Map<K, V> map) {
		this.map = map;
	}
    /*使用tryLock()方法写*/
    public V put(K key,V value){
    	while (true){
    		if(writeLock.tryLock()){
              try {
	              System.out.println("put"+key+"value"+value);
	              return map.put(key,value);
              }finally {
              	writeLock.unlock();
              }
		    }
	    }
    }

    public V get(K key){
    	while (true){
    		if(writeLock.tryLock()){
    			try {
    				V value = map.get(key);
				    System.out.println("get"+key+""+value);
			    }finally {
    				writeLock.unlock();
			    }
		    }
	    }
    }

	public static void main(String[] args) {
		final ReadAndWriteLock<String,Integer> rw = new ReadAndWriteLock(new HashMap());
		ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i=0;i<20;i++){
        	executorService.execute(new TestRunnable(rw));
        }
        executorService.shutdown();
	}

	static class TestRunnable implements Runnable{
		private final ReadAndWriteLock<String,Integer> rw;
        private final String KEY = "X";
		public TestRunnable(ReadAndWriteLock<String, Integer> rw) {
			this.rw = rw;
		}

		@Override
		public void run(){
			Random random = new Random();
			int r = random.nextInt(100);
			if(r<40){
               rw.put(KEY,r);
			}else {
				rw.get(KEY);
			}


		}
	}
}
